package cn.tedu.mall.front.service.impl;

import cn.tedu.mall.common.exception.CoolSharkServiceException;
import cn.tedu.mall.common.restful.ResponseCode;
import cn.tedu.mall.front.mapper.FrontSkuMapper;
import cn.tedu.mall.front.service.IFrontSkuService;
import cn.tedu.mall.pojo.order.dto.OrderItemAddDTO;
import cn.tedu.mall.pojo.product.model.Spu;
import cn.tedu.mall.pojo.product.vo.SkuStandardVO;
import cn.tedu.mall.pojo.product.vo.SpuStandardVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
@DubboService
@Service
@Slf4j
public class FrontSkuServiceImpl extends FrontCacheServiceImpl<SkuStandardVO> implements IFrontSkuService {
    @Autowired
    private FrontSkuMapper frontSkuMapper;
    //id是spuId
    private static final String FRONT_SKUS_PREFIX="front:skus:";
    private static final String FRONT_SKUS_LOCK_SUFFIX=".lock";
    @Override
    public List<SkuStandardVO> getSkus(Long spuId) {
        //TODO 布隆过滤器需求
        //击穿处理 分布式抢锁
        //缓存cache-aside 流程 使用List类型存储
        String skusKey=FRONT_SKUS_PREFIX+spuId;
        //没有存储和获取list缓存的方法 getListCache(skusKey)
        List<SkuStandardVO> caches=getListCache(skusKey);
        if (caches ==null || caches.size()== 0){
            //抢锁 生成锁key值 randCode
            String skusLockKey=skusKey+FRONT_SKUS_LOCK_SUFFIX;
            String randCode=new Random().nextInt(9000)+1000+"";
            try {
                //抢锁
                boolean haveLock = tryLock(skusLockKey, randCode);
                if (!haveLock){
                    Thread.sleep(5000);
                    return getListCache(skusKey);
                }
                List<SkuStandardVO> skuStandardVOS =
                        frontSkuMapper.selectSkusBySpuId(spuId);
                if (skuStandardVOS == null) {
                    throw new CoolSharkServiceException(ResponseCode.NOT_FOUND,
                            "当前spu下没有sku数据");
                }
                //没有setListCache方法
                setListCache(skusKey, skuStandardVOS,
                        60 * 60 * 24L + new Random().nextInt(10000), TimeUnit.SECONDS);
                return skuStandardVOS;
            }catch (Exception e){
                log.error("出现异常，e:{}",e.getMessage());
            }finally {
                releaseLock(skusLockKey,randCode);
            }
        }
        return caches;
        //有没有值判断

    }

    @Override
    public SkuStandardVO getSku(Long skuId) {
        //引入缓存的前提,这个方法也要考虑击穿,穿透的问题,考虑雪崩的问题
        return frontSkuMapper.selectSkuById(skuId);
    }

    @Override
    public List<SkuStandardVO> listSkuByIds(List<Long> ids) {
        List<SkuStandardVO> skuStandardVOS=new ArrayList<>();
        for (Long id : ids) {
            SkuStandardVO skuStandardVO = frontSkuMapper.selectSkuById(id);
            skuStandardVOS.add(skuStandardVO);
        }
        return skuStandardVOS;
    }

    @Override
    public void reduceSkusCounts(List<OrderItemAddDTO> items, String sn) {

    }

    @Override
    public void returnStock(String sn) {

    }
}
